﻿using System.Collections.Generic;
using System.ComponentModel;

namespace Twi.COMMON.WPF
{
    public class CheckBoxTreeViewItem : INotifyPropertyChanged
    {
        #region Data

        bool? _isChecked = false;
        object _tag = null;

        private bool _cascadeCheck = true;

        /// <summary>
        /// 是否级联勾选其他选项框
        /// </summary>
        public bool CascadeCheck { get { return _cascadeCheck; } }

        public object Tag { get { return _tag; } set { _tag = value; } }

        CheckBoxTreeViewItem _parent;

        #endregion // Data

        #region CreateFoos
        
        public CheckBoxTreeViewItem(string name)
        {
            this.Name = name;
            this.Children = new List<CheckBoxTreeViewItem>();
        }

        public CheckBoxTreeViewItem(string name, bool cascadeCheck)
        {
            this.Name = name;
            this.Children = new List<CheckBoxTreeViewItem>();

            _cascadeCheck = cascadeCheck;
        }

        public void Initialize()
        {
            foreach (CheckBoxTreeViewItem child in this.Children)
            {
                child._parent = this;
                child.Initialize();
            }
        }

        #endregion // CreateFoos

        #region Properties

        public List<CheckBoxTreeViewItem> Children { get; private set; }

        public bool IsInitiallySelected { get; set; }

        public string Name { get; private set; }

        #region IsChecked

        /// <summary>
        /// Gets/sets the state of the associated UI toggle (ex. CheckBox).
        /// The return value is calculated based on the check state of all
        /// child FooViewModels.  Setting this property to true or false
        /// will set all children to the same check state, and setting it 
        /// to any value will cause the parent to verify its check state.
        /// </summary>
        public bool? IsChecked
        {
            get { return _isChecked; }
            set
            {
                if (_cascadeCheck)
                {
                    this.SetIsChecked(value, true, true);
                }
                else 
                {
                    _isChecked = value;
                }
            }
        }

        void SetIsChecked(bool? value, bool updateChildren, bool updateParent)
        {
            if (value == _isChecked)
                return;

            _isChecked = value;

            if (updateChildren && _isChecked.HasValue)
                this.Children.ForEach(c => c.SetIsChecked(_isChecked, true, false));

            if (updateParent && _parent != null)
                _parent.VerifyCheckState();

            this.OnPropertyChanged("IsChecked");
        }

        void VerifyCheckState()
        {
            bool? state = null;
            for (int i = 0; i < this.Children.Count; ++i)
            {
                bool? current = this.Children[i].IsChecked;
                if (i == 0)
                {
                    state = current;
                }
                else if (state != current)
                {
                    state = null;
                    break;
                }
            }
            this.SetIsChecked(state, false, true);
        }

        #endregion // IsChecked

        #region IsExpanded
        /// <summary>
        /// 折叠状态
        /// </summary>
        private bool _isExpanded;

        /// <summary>
        /// 是否展开
        /// </summary>
        public bool IsExpanded
        {
            get { return _isExpanded; }
            set
            {
                if (value != _isExpanded)
                {
                    //折叠状态改变
                    _isExpanded = value;
                    OnPropertyChanged("IsExpanded");
                }
            }
        }
        /// <summary>
        /// 设置所有子项展开状态
        /// </summary>
        /// <param name="isExpanded"></param>
        public void SetChildrenExpanded(bool isExpanded)
        {
            foreach (CheckBoxTreeViewItem child in Children)
            {
                child.IsExpanded = isExpanded;
                child.SetChildrenExpanded(isExpanded);
            }
        }
        #endregion 

        #endregion // Properties

        #region INotifyPropertyChanged Members

        void OnPropertyChanged(string prop)
        {
            if (this.PropertyChanged != null)
                this.PropertyChanged(this, new PropertyChangedEventArgs(prop));
        }

        public event PropertyChangedEventHandler PropertyChanged;

        #endregion

        
    }
}
